package UserSessionManager

import (
	LogUtils "IMServices/LogService"
	"errors"
	"net"
	"strconv"
	"time"
)

type TcpClientInterface interface {
	Write([]byte)
	IsConnStillAlive()
}

type ClientManagerInterface interface {
	AddConn(tcpClient TcpClient)
	DelConn(userId int64)
	GetConn(userId int64) (TcpClient, error)
	SendToConn(userId int64, pack []byte)
	CloseConn(userId int64)
}

// TcpClient 登录成功后存储正式连接在这
type TcpClient struct {
	//ip
	Ip string
	//端口
	Port int
	//连接时间
	LoginTime time.Time
	//客户端socket
	conn net.Conn

	UserId int64

	UserName string
}

type ClientManager struct {
	clientSessionMap map[int64]TcpClient
}

var ClientInstance ClientManager

func InitNewClientManager() {
	ClientInstance.clientSessionMap = make(map[int64]TcpClient)
}

// IsConnStillAlive 连接登录后开始每分钟检测存活
func (t *TcpClient) IsConnStillAlive() {
	ticker := time.NewTicker(60 * time.Second) // 创建一个定时器，每隔 1 秒触发一次
	defer ticker.Stop()                        // 关闭定时器

	for {
		select {
		case <-ticker.C:
			buf := make([]byte, 0)
			_, err := t.conn.Read(buf)
			if err != nil {
				//return false // 连接已经关闭  删除连接消息通道发出
			}
		}
	}

}

func (t *TcpClient) Write(pack []byte) {
	_, err := t.conn.Write(pack)
	if err != nil {
		LogUtils.LogError("Write data error")
		return
	}
}
func (clientManager *ClientManager) AddConn(tcpClient TcpClient) {
	clientManager.clientSessionMap[tcpClient.UserId] = tcpClient
}

func (clientManager *ClientManager) DelConn(userId int64) {
	tcpClient, err := clientManager.GetConn(userId)
	if err == nil {
		err := tcpClient.conn.Close()
		if err != nil {
			LogUtils.LogError("链接关闭失败 " + strconv.FormatInt(userId, 10))
			return
		}
		delete(clientManager.clientSessionMap, userId)
	}
}

func (clientManager *ClientManager) GetConn(userId int64) (TcpClient, error) {
	if _, ok := clientManager.clientSessionMap[userId]; ok {
		client := clientManager.clientSessionMap[userId]
		return client, nil
	} else {
		LogUtils.LogError("连接不存在")
		return TcpClient{}, errors.New("连接不存在")
	}
}
func (clientManager *ClientManager) SendToConn(userId int64, pack []byte) {
	client, ok := clientManager.clientSessionMap[userId]
	if ok {
		client.Write(pack)
	}
}

func (clientManager *ClientManager) CloseConn(userId int64) {
	client, ok := clientManager.clientSessionMap[userId]
	if ok {
		err := client.conn.Close()
		if err != nil {
			LogUtils.LogError("send to client error")
			return
		}
	}
}
